package com.rw.coco.handler.message.reply.handler.command.sender;

import com.rw.coco.expression.DiceExpression;
import com.rw.coco.expression.RollCommandParser;
import com.rw.coco.handler.message.event.CocoMessageEvent;
import com.rw.coco.handler.message.reply.handler.command.exception.global.NumberOverflowException;
import com.rw.tool.util.expression.exception.ExpressionException;
import com.rw.tool.util.string.StringUtil;
import lombok.Getter;

/**
 * Roll点发送器
 */
@Getter
public class RollSender {
    // 聊天事件
    private final CocoMessageEvent cocoMessageEvent;

    // 表达式解析器
    private final RollCommandParser parser;

    // 默认骰
    private final int defaultDice;

    // 解析出的表达式
    private String expression;

    // 解析出的异常
    private ExpressionException expressionException;
    private NumberOverflowException numberOverflowException;

    public RollSender(CocoMessageEvent cocoMessageEvent, String command, boolean simple) {
        this.cocoMessageEvent = cocoMessageEvent;

        // 获取指令，解析指令
        parser = new RollCommandParser(command);
        // 得到默认的骰子和指令
        defaultDice = cocoMessageEvent.getAccountModel().getDefaultDice();

        try {
            // 获取完整表达式
            expression = getExpression(parser.getExpression(), defaultDice, simple);
        } catch (ExpressionException e) {
            expressionException = e;
        } catch (NumberOverflowException e) {
            numberOverflowException = e;
        }
    }

    public RollSender(CocoMessageEvent cocoMessageEvent, String command) {
        this(cocoMessageEvent, command, false);
    }

    /**
     * 根据骰子表达式和默认骰子算出结果，并给出完整的表达式
     *
     * @param rawExpression 骰子表达式
     * @param defaultDice   默认的骰子
     * @return 带结果的完整表达式
     */
    private static String getExpression(String rawExpression, int defaultDice, boolean simple) {
        // 构造骰子表达式
        DiceExpression diceExpression;
        if (StringUtil.isBlank(rawExpression)) {
            final String defaultDiceExpression = "1D100";
            diceExpression = DiceExpression.parse(defaultDiceExpression, defaultDice);
        } else {
            diceExpression = DiceExpression.parse(rawExpression, defaultDice);
        }

        return diceExpression.toCompleteString(simple);
    }

    public boolean success() {
        return expression != null;
    }
}
